import { exec } from 'child_process';
import * as util from 'util';
import * as fs from 'fs/promises';
import * as path from 'path';
import * as os from 'os';
import logger from './logger';

// 将 exec 转换为 Promise 版本
const execAsync = util.promisify(exec);

/**
 * 本地系统环境信息接口
 */
interface SystemEnvironment {
    os: string;
    shell: string;
    env: { [key: string]: string };
    paths: string[];
    tools: string[];
}

/**
 * 执行本地命令并返回结果
 */
export async function executeCommand(command: string, options: { cwd?: string; timeout?: number } = {}) {
    try {
        logger.debug(`执行命令: ${command}`, { cwd: options.cwd });
        const { stdout, stderr } = await execAsync(command, {
            cwd: options.cwd || process.cwd(),
            timeout: options.timeout || 30000,
            maxBuffer: 1024 * 1024 * 10
        });

        if (stderr) {
            logger.warn(`命令产生了错误输出: ${stderr}`);
        }

        return { success: true, stdout, stderr };
    } catch (error) {
        logger.error(`命令执行失败: ${error.message}`, { command, error });
        return {
            success: false,
            error: error.message,
            stdout: error.stdout,
            stderr: error.stderr,
            code: error.code
        };
    }
}

/**
 * 获取本地开发环境信息
 */
export async function getDevEnvironment(): Promise<SystemEnvironment> {
    const shell = process.env.SHELL || process.env.COMSPEC || '';
    const paths = process.env.PATH ? process.env.PATH.split(path.delimiter) : [];

    // 检测常用开发工具
    const commonTools = ['git', 'node', 'npm', 'python', 'java', 'gcc'];
    const availableTools = [];

    for (const tool of commonTools) {
        const command = process.platform === 'win32' ? 'where' : 'which';
        try {
            await execAsync(`${command} ${tool}`);
            availableTools.push(tool);
        } catch {
            // 工具不可用，跳过
        }
    }

    return {
        os: `${os.type()} ${os.release()}`,
        shell: path.basename(shell),
        env: process.env as { [key: string]: string },
        paths,
        tools: availableTools
    };
}

/**
 * 获取系统资源使用情况
 */
export function getSystemResources() {
    const cpus = os.cpus();
    const totalMem = os.totalmem();
    const freeMem = os.freemem();
    const usedMem = totalMem - freeMem;

    return {
        cpu: {
            cores: cpus.length,
            model: cpus[0].model,
            speed: cpus[0].speed,
            usage: process.cpuUsage()
        },
        memory: {
            total: totalMem,
            free: freeMem,
            used: usedMem,
            usage: (usedMem / totalMem) * 100
        },
        uptime: os.uptime(),
        loadavg: os.loadavg()
    };
}

/**
 * 检查本地项目环境
 */
export async function checkProjectEnvironment(projectPath: string) {
    const results = {
        type: 'unknown',
        dependencies: [] as string[],
        configs: [] as string[],
        environment: {} as any
    };

    try {
        // 检查项目类型和配置文件
        const files = await fs.readdir(projectPath);

        // Node.js 项目检查
        if (files.includes('package.json')) {
            results.type = 'nodejs';
            const packageJson = JSON.parse(
                await fs.readFile(path.join(projectPath, 'package.json'), 'utf8')
            );
            results.dependencies = Object.keys({
                ...packageJson.dependencies,
                ...packageJson.devDependencies
            });
            results.environment = {
                nodeVersion: process.version,
                npmVersion: (await execAsync('npm -v')).stdout.trim()
            };
        }

        // Python 项目检查
        else if (files.includes('requirements.txt')) {
            results.type = 'python';
            const requirements = await fs.readFile(
                path.join(projectPath, 'requirements.txt'),
                'utf8'
            );
            results.dependencies = requirements
                .split('\n')
                .filter(line => line.trim() && !line.startsWith('#'))
                .map(line => line.split('==')[0]);
        }

        // 收集配置文件
        const configFiles = [
            '.env',
            '.gitignore',
            'tsconfig.json',
            'babel.config.js',
            'webpack.config.js',
            'vite.config.js',
            'jest.config.js'
        ];

        results.configs = files.filter(file => configFiles.includes(file));

    } catch (error) {
        logger.error(`检查项目环境失败: ${error.message}`, { projectPath, error });
    }

    return results;
}

/**
 * 创建本地开发环境配置
 */
export async function createDevConfig(projectPath: string, options: any = {}) {
    try {
        const configDir = path.join(projectPath, '.devconfig');
        await fs.mkdir(configDir, { recursive: true });

        // 保存环境信息
        const envInfo = await getDevEnvironment();
        await fs.writeFile(
            path.join(configDir, 'environment.json'),
            JSON.stringify(envInfo, null, 2)
        );

        // 保存系统资源基准信息
        const resourceInfo = getSystemResources();
        await fs.writeFile(
            path.join(configDir, 'resources.json'),
            JSON.stringify(resourceInfo, null, 2)
        );

        // 创建项目特定的配置
        const projectConfig = {
            name: path.basename(projectPath),
            type: options.type || 'unknown',
            created: new Date().toISOString(),
            settings: options
        };

        await fs.writeFile(
            path.join(configDir, 'project.json'),
            JSON.stringify(projectConfig, null, 2)
        );

        return { success: true, configPath: configDir };
    } catch (error) {
        logger.error(`创建开发配置失败: ${error.message}`, { projectPath, error });
        return { success: false, error: error.message };
    }
}

/**
 * 管理本地开发环境变量
 */
export async function manageEnvVariables(projectPath: string, action: 'get' | 'set' | 'delete', variables: { [key: string]: string } = {}) {
    const envPath = path.join(projectPath, '.env');

    try {
        switch (action) {
            case 'get': {
                try {
                    const content = await fs.readFile(envPath, 'utf8');
                    return content.split('\n').reduce((vars: any, line) => {
                        const [key, value] = line.split('=').map(s => s.trim());
                        if (key && value) vars[key] = value;
                        return vars;
                    }, {});
                } catch (error) {
                    return {};
                }
            }

            case 'set': {
                const existing = await manageEnvVariables(projectPath, 'get');
                const newContent = Object.entries({
                    ...existing,
                    ...variables
                })
                    .map(([key, value]) => `${key}=${value}`)
                    .join('\n');
                await fs.writeFile(envPath, newContent);
                return { success: true };
            }

            case 'delete': {
                const existing = await manageEnvVariables(projectPath, 'get');
                Object.keys(variables).forEach(key => delete existing[key]);
                const newContent = Object.entries(existing)
                    .map(([key, value]) => `${key}=${value}`)
                    .join('\n');
                await fs.writeFile(envPath, newContent);
                return { success: true };
            }

            default:
                throw new Error(`不支持的操作: ${action}`);
        }
    } catch (error) {
        logger.error(`管理环境变量失败: ${error.message}`, { projectPath, action, error });
        return { success: false, error: error.message };
    }
}

/**
 * 创建项目备份
 */
export async function backupProject(projectPath: string, options: { exclude?: string[] } = {}) {
    try {
        const backupDir = path.join(projectPath, '.backups');
        await fs.mkdir(backupDir, { recursive: true });

        const timestamp = new Date().toISOString().replace(/[:\.]/g, '-');
        const backupName = `backup-${timestamp}`;
        const backupPath = path.join(backupDir, backupName);

        // 创建备份目录
        await fs.mkdir(backupPath);

        // 复制项目文件
        const excludePatterns = [
            'node_modules',
            '.git',
            '.backups',
            'dist',
            'build',
            ...(options.exclude || [])
        ];

        async function copyDir(src: string, dest: string) {
            const entries = await fs.readdir(src, { withFileTypes: true });

            for (const entry of entries) {
                const srcPath = path.join(src, entry.name);
                const destPath = path.join(dest, entry.name);

                if (excludePatterns.includes(entry.name)) {
                    continue;
                }

                if (entry.isDirectory()) {
                    await fs.mkdir(destPath, { recursive: true });
                    await copyDir(srcPath, destPath);
                } else {
                    await fs.copyFile(srcPath, destPath);
                }
            }
        }

        await copyDir(projectPath, backupPath);

        // 创建备份信息文件
        const backupInfo = {
            timestamp: new Date().toISOString(),
            originalPath: projectPath,
            excludedPatterns: excludePatterns
        };

        await fs.writeFile(
            path.join(backupPath, 'backup-info.json'),
            JSON.stringify(backupInfo, null, 2)
        );

        return {
            success: true,
            backupPath,
            backupName
        };
    } catch (error) {
        logger.error(`创建项目备份失败: ${error.message}`, { projectPath, error });
        return { success: false, error: error.message };
    }
}